package com.ctshk.sapp.payment.controller;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.ctshk.common.annotations.OperationLogAnnotation;
import com.ctshk.common.dto.Result;
import com.ctshk.common.enums.OperationLogModel;
import com.ctshk.common.enums.OperationLogType;
import com.ctshk.common.enums.OrderSource;
import com.ctshk.common.model.AppReq;
import com.ctshk.common.utils.RequestUtil;
import com.ctshk.rpc.payment.dto.MastercardPayHostedDto;
import com.ctshk.rpc.payment.dto.PayDetailsDTO;
import com.ctshk.rpc.payment.dto.RefundDetailsDTO;
import com.ctshk.rpc.payment.enums.PaymentMethod;
import com.ctshk.rpc.payment.req.CallPayReq;
import com.ctshk.rpc.payment.req.RefundReq;
import com.ctshk.rpc.payment.service.IPayRecordService;
import com.ctshk.rpc.payment.service.IPayService;
import com.ctshk.rpc.payment.service.IRefundRecordService;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
 * @BelongsProject: ctshk-cloud
 * @BelongsPackage: com.ctshk.sapp.payment.controller
 * @Author: hef
 * @CreateTime: 2021-04-20 18:12
 * @Description: 描述
 */
@Slf4j
@RestController
@RequestMapping("/pay")
@Api(value = "支付服务", tags = "支付服务")
public class PayController {
    @DubboReference
    private IPayService payService;
    @DubboReference
    private IPayRecordService payRecordService;
    @DubboReference
    private IRefundRecordService iRefundRecordService;

    @ApiOperation(value = "支付服务-唤起支付", notes = "支付服务-唤起支付")
    @OperationLogAnnotation(operModul = OperationLogModel.ORDER, operType = OperationLogType.UPDATE, operTitle = "机场快线-订单中心-唤起支付", operDesc = "机场快线-订单中心-唤起支付")
    @PostMapping("/callPay")
    public Result callPay(@RequestBody @Valid CallPayReq callPayReq, @ApiIgnore AppReq appReq, HttpServletResponse response) {
        Result result = payService.callPay(callPayReq);
        log.info("【支付服务-唤起支付】返回数据,data{}", result);
        if (appReq.getOrderSource().equals(OrderSource.H5.getCode()) && PaymentMethod.isStream(callPayReq.getPaymentMethodCode())) {
            response.setContentType("text/html");
            response.setCharacterEncoding("UTF-8");
            try {
                response.getWriter().write(String.valueOf(result.getData()));
                response.getWriter().flush();
                response.getWriter().close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    @ApiOperation(value = "支付服务-第三方回调", notes = "支付服务-第三方回调")
    @RequestMapping("/callback")
    public Object callback(HttpServletRequest request) {
        log.info("【支付服务-第三方回调】第三方回调入口, method:{}", request.getMethod());
        Map<String, String[]> parameterMap = request.getParameterMap();
        Map<String, String> map = getParameterMap(parameterMap);
        if (CollectionUtils.isEmpty(map)) {
            Map<String, Object> body = RequestUtil.getBody(request);
            Map<String, String> bodyMap = new HashMap<>();
            body.forEach((k, v) -> {
                bodyMap.put(k, v.toString());
            });
            map = bodyMap;
        }
        log.info("【支付服务-第三方回调】第三方回调入口, data:{}", JSON.toJSONString(map));
        if (map.size() == 0) return "failure";
        return payService.callback(map);
    }

    @ApiOperation(value = "机场快线-支付页面-轮询支付结果", notes = "机场快线-支付页面-轮询支付结果")
//    @OperationLogAnnotation(operModul = OperationLogModel.ORDER, operType = OperationLogType.QUERY, operTitle = "机场快线-支付页面-轮询支付结果", operDesc = "机场快线-支付页面-轮询支付结果")
    @GetMapping("/polling/pay/result")
    public Result<Integer> queryPayResult(@RequestParam("orderId") Long orderId) {
        return payService.pollingPayResult(orderId);
    }

    private Map<String, String> getParameterMap(Map<String, String[]> parameterMap) {
        Map<String, String> map = new HashMap<>(parameterMap.size());
        for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
            String k = entry.getKey();
            String[] v = entry.getValue();
            String value = Arrays.toString(v);
            map.put(k, value.substring(1, value.length() - 1));
        }
        return map;
    }

    /**
     * 查询交易信息
     *
     * @param orderNumber
     * @return
     */
    @GetMapping("/queryTransactionInfo/{orderNumber}")
    public Result<PayDetailsDTO> queryTransactionInfo(@PathVariable String orderNumber) {
        return Result.success(payRecordService.queryTransactionInfo(orderNumber));
    }


    /**
     * 退款申请
     *
     * @param req
     * @return
     */
    @PutMapping("/refund")
    public Result refund(@RequestBody RefundReq req) {
        return Result.success(payService.refund(req));
    }

    /**
     * 获取退款详情
     *
     * @param orderNumber
     * @param refundNumber
     * @return
     */
    @GetMapping("/getRefundDetail")
    public Result<RefundDetailsDTO> getRefundDetail(@RequestParam String orderNumber, @RequestParam String refundNumber) {
        return Result.success(iRefundRecordService.getRefundDetail(orderNumber, refundNumber));
    }


    @GetMapping("/refundNotify")
    public Object refundNotify(HttpServletRequest request) {
        Map<String, String[]> parameterMap = request.getParameterMap();
        log.info("{}收到refundNotify,回调参数:{}", LocalDateTime.now(), JSON.toJSONString(parameterMap));
        return iRefundRecordService.refundNotify(getParameterMap(parameterMap));
    }
}
